package excel

import (
	"errors"
	"fmt"

	"github.com/tealeg/xlsx"
)

type Import interface {
	Row(data []string) (interface{}, error)
	Insert([]interface{}) error
}

type IDo interface {
	Import
	canUse() error
	lock()
	unlock()
	Url() string
	FilePath() string
	Do() ([]string, error)
}

type Do struct {
	Import
	chanImport chan int
	url        string
	filePath   string
	err        error
}

func (this *Do) canUse() error {
	if len(this.chanImport) == 0 {
		return errors.New("正在导入,请稍后再试")
	}
	return nil
}

func (this *Do) lock() {
	<-this.chanImport
}

func (this *Do) unlock() {
	this.chanImport <- 0
}

func (this *Do) Do() ([]string, error) {
	return do(this)
}

func (this *Do) checkErr() {
	if this.Import == nil {
		this.err = errors.New("传入参数不能为nil")
	}
}

func NewImport(im Import, url string) *Do {
	l := &Do{
		Import:     im,
		chanImport: make(chan int, 1),
		url:        url,
		filePath:   "./download",
	}
	l.checkErr()
	l.unlock()
	return l
}

func do(im *Do) ([]string, error) {
	if im.err != nil {
		return nil, im.err
	}
	if err := im.canUse(); err != nil {
		return nil, err
	}
	im.lock()
	defer im.unlock()

	filePath := im.filePath //"./download"
	//验证文件格式并下载
	fullpath, err := DownloadExcel(filePath, im.url)
	if err != nil {
		return nil, err
	}

	xlFile, err := xlsx.OpenFile(fullpath)
	if err != nil {
		return nil, err
	}

	var msg []string //记录错误信息
	data := []interface{}{}
	for i, sheet := range xlFile.Sheets { //页
		for k, row := range sheet.Rows { //行
			if k == 0 { //排除第一行
				continue
			}
			cell := []string{}
			for _, v := range row.Cells {
				cell = append(cell, v.String())
			}
			if len(cell) == 0 {
				continue
			}
			l, err := im.Row(cell)
			if err != nil {
				msg = append(msg, fmt.Sprintf("第%d页第%d行", i, k)+err.Error())
				continue
			}
			//测试空行会不会读取出来
			if l != nil {
				data = append(data, l)
			}
		}
	}
	return msg, im.Insert(data)
}
